package br.com.felix.easyclearcase.tasks;

import java.util.ArrayList;
import java.util.List;

/**
 * A Task that starts when all of its child tasks are completed.
 * @see Task
 * */
public abstract class TaskGroup extends Task {
	
	/**
	 * List of child tasks
	 * */
	protected List<Task> tasks = new ArrayList<Task>();
	
	/**
	 * Number of completedTasks. Used to know when this task should start.
	 * */
	protected int completedTasks = 0;
	
	
	/**
	 * Adds a task to the list of child tasks of this group.
	 * */
	public void add(Task task){
		tasks.add(task);
		task.addTaskStatusListener(new TaskStatusListener(){
			@Override
			public void statusChanged(TaskStatus oldValue, TaskStatus newValue) {
				switch(newValue){
					case CANCELLED:
					case COMPLETE_FAIL:
					case COMPLETE_SUCCESS:
						completedTasks++;
				}
				if(completedTasks==tasks.size()){
					groupReadyToStart();
				}
			}
		});
	}
	
	
	
	/**
	 * Method called when all tasks of the group are completed.
	 * If not overwritten, this task won't do anything, just change the status to COMPLETE_SUCCESS.
	 * */
	protected void groupReadyToStart(){
		changeStatus(TaskStatus.COMPLETE_SUCCESS);
	}


	/**
	 * Cancels the taskgroup and all the child tasks.
	 * Calls the groupReadyToStart at the end.
	 * */
	@Override
	public void cancel() {
		cancelled = true;
		for(Task t:tasks){
			if(t.getStatus()==TaskStatus.NOT_STARTED){
				t.cancel();
			}
		}
		changeStatus(TaskStatus.CANCELLED);
		groupReadyToStart();
	}
	


	/**
	 * Taskgroup priority is NORMAL.
	 * */
	@Override
	public TaskPriority getTaskPriority() {
		return TaskPriority.NORMAL;
	}
	
	
	/**
	 * Start all the tasks in the order they were added.
	 * */
	public void startTasks(){
		for(Task task:tasks){
			task.start();
		}
	}
	
	public String toString(){
		StringBuilder strb = new StringBuilder();
		for(int i=0; i<tasks.size();i++){
			strb.append(i).append("  ***************\n");
			strb.append(tasks.get(i).toString());
			strb.append("\n");
		}
		return strb.toString();
	}
}
